#ifndef F7C6A079_DF2D_4693_8FF9_D4AFA51D8062
#define F7C6A079_DF2D_4693_8FF9_D4AFA51D8062
#include<iostream>
#include"level.hpp"
#include<memory>
#include"message.hpp"
#include<ctime>
#include<vector>

namespace mian_yang
{
    class FormatItem
    {
    public:
        using ptr = std::shared_ptr<FormatItem>;
        virtual void format(std::ostream& out, LogMsg& msg) = 0;
    };

    class MsgFormatItem : FormatItem
    {
    public:
        void format(std::ostream& out, LogMsg& msg) override
        {
            out << msg._payload;
        }
    };


    class LevelFormatItem : FormatItem
    {
    public:
        void format(std::ostream& out, LogMsg& msg) override
        {
            out << LogLevel::toString(msg._level);
        }
    };
    class TimeFormatItem : FormatItem
    {
    public:
        TimeFormatItem(const std::string& fmt = "%H:%M:%S")
        :_time_fmt(fmt)
        {}
        void format(std::ostream& out, LogMsg& msg) override
        {
            struct tm t;  //这个能够将时间戳保存
            localtime_r(&msg._ctime, &t);
            char tmp[32] = {0};
            strftime(tmp, 31, _time_fmt.c_str(), &t); //strftime能够将tm对象里面的时间以字符串中所给出的格式传到tmp里面。

            out << tmp;
        }
    private:
        std::string _time_fmt; //时间格式， %H 
    };
    class FileFormatItem : FormatItem
    {
    public:
        void format(std::ostream& out, LogMsg& msg) override
        {
            out << msg._file;
        }
    };

    class LineFormatItem : FormatItem
    {
    public:
        void format(std::ostream& out, LogMsg& msg) override
        {
            out << msg._line;
        }
    };
    class tidFormatItem : FormatItem
    {
    public:
        void format(std::ostream& out, LogMsg& msg) override
        {
            out << msg._tid.get_id();
        }
    };
    class NLineFormatItem : FormatItem
    {
    public:
        void format(std::ostream& out, LogMsg& msg) override
        {
            out << "\n";
        }
    };
    class TabFormatItem : FormatItem
    {
    public:
        void format(std::ostream& out, LogMsg& msg) override
        {
            out << "\t";
        }
    };

    class OtherFormatItem : FormatItem
    {
    public:
        OtherFormatItem(std::string str) : _str(str){}
        void format(std::ostream& out, LogMsg& msg) override
        {
            out << _str;
        }
    private: 
        std::string _str;
    };

    class Formatter
    {
    public:
        Formatter(const std::string& pattern = "%d{%H:%M:%S}][%t][%c][%f:%l][%p]%T%m%n")
        : _pattern(pattern)
        {}

        //对msg进行格式化
        void format(std::ostream& out, LogMsg& msg);
        std::string format(LogMsg& msg);

        //对格式化规则字符串进行解析
        bool parsePattern();

    private:
        FormatItem::ptr createItem(const std::string& key, const std::string& val);

    private:
        std::string _pattern;
        std::vector<FormatItem::ptr> _items;
    };

}

#endif /* F7C6A079_DF2D_4693_8FF9_D4AFA51D8062 */
